# -*- coding: utf-8 -*-
import os, time, cv2, subprocess
import numpy as np
from threading import Thread
from abc import abstractmethod, ABCMeta
from .logger import logger
from .utils import load_img, find_img, log_print


"""
命令操作
"""

adbShell = "adb shell {cmdStr}"


#----------------------------------------------------------------------
# excute by adb
def adb_execute(cmd):
    cmd_str = adbShell.format(cmdStr = cmd)
    logger.debug(f"cmd: {cmd_str}")
    os.system(cmd_str)


#----------------------------------------------------------------------
# adb screencap
# 不同系统的换行符不一样，需要替换
NEWLINE = b'\r\n'
SCREEN_STREAM = None

def adb_screencap(refresh_screen: bool = True):
    global SCREEN_STREAM
    if refresh_screen:
        with subprocess.Popen('adb shell screencap -p',
                              shell = True, stdout = subprocess.PIPE) as process:
            stream = process.stdout.read()
            stream = stream.replace(NEWLINE, b'\n')
            np_array = np.frombuffer(stream, np.int8)
            SCREEN_STREAM = cv2.imdecode(np_array, cv2.IMREAD_COLOR)
    else:
        logger.debug("===== get screen from cache. ")
    return SCREEN_STREAM


#----------------------------------------------------------------------
# 等待
def adb_action_wait(second: int = 1):
    time.sleep(second)
    return True


#----------------------------------------------------------------------
# 关闭应用
def adb_stop(app_name: str):
    return adb_execute(f"am force-stop {app_name}")


#----------------------------------------------------------------------
# 点击
def adb_action_tap(pos: tuple, ms: int = 0):
    return adb_execute(f"input tap {pos[0]} {pos[1]}")


#----------------------------------------------------------------------
# 滑动
def adb_action_swipe(pos: tuple, to_pos: tuple, dur: int = 100):
    return adb_execute(f"input swipe {pos[0]} {pos[1]} {to_pos[0]} {to_pos[1]} {dur}")


#----------------------------------------------------------------------
# 根据图片获取 crop 信息
CROP_DICT = {
    # combat
    "./data/aed_combat.png" : (30, 20, 150, 60),
    "./data/aed_combat_hk.png" : (30, 20, 150, 60),
    # menu
    "./data/aed_button_menu.png" : (40, 600, 130, 700),
    "./data/aed_button_menu_hk.png" : (40, 600, 130, 700),
    # yes
    "./data/aed_button_yes.png" : (640, 250, 900, 460),
    "./data/aed_button_yes_hk.png" : (640, 250, 900, 460),
    # head6 lv max
    "./data/aed_head6_lv_max.png" : (1080, 460, 1130, 500),
    # revive item
    "./data/aed_revive_iname_hk.png" : (600, 150, 740, 560),
    # badges
    "./data/aed_badge_bottom_hk.png" : (1050, 0, 1280, 720),
    "./data/aed_badge_top_hk.png" : (1050, 0, 1280, 720),
    # stage4
    "./data/aed_stage4.png" : (330, 220, 510, 310)
}


#----------------------------------------------------------------------
# 查找目标图片
def adb_action_find_img(target_img_filename: str, m_degree: float = 0.05,
                        refresh_screen: bool = True, crop: tuple = True, log: bool = False):
    target_stream = load_img(target_img_filename)
    cv_stream = adb_screencap(refresh_screen)
    if crop == True:
        crop = CROP_DICT.get(target_img_filename, False)
    return find_img(target_stream, cv_stream, m_degree, crop, log)


#----------------------------------------------------------------------
# 直到查找到目标，最多支持 10 个循环
def adb_action_until_find_img(target_img_filename: str, m_degree: float = 0.05,
                              refresh_screen: bool = True, crop: tuple = True,
                              click_pos: tuple = None, final_click: bool = False,
                              delay: float = 2, max_times = 10, log: bool = False):
    log_print(f"start to find: {target_img_filename}", log)
    for idx in range(max_times):
        res = adb_action_find_img(target_img_filename, m_degree, refresh_screen, crop, log)
        if res:
            log_print(f"target img: {target_img_filename} @ {res}", log)
            if final_click:
                adb_action_tap(res)
            return res
        else:
            if click_pos:
                adb_action_tap(click_pos)
            adb_action_wait(delay)
    log_print("fail to find img. ", log)
    return False
